package com.android.dialer.extendboard;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class UsbHelperTCP {
    private static final String TAG = "UsbHelperTCP";
    private static final int TCP_PORT = 12345; // 本地 TCP 端口
    private Context mContext;
    private Handler mHandler;
    private ServerSocket serverSocket;
    private Thread tcpServerThread;
    private volatile boolean isRunning = false;
    private volatile Socket clientSocket; // 当前有效的客户端 Socket
    private DataParseHelper dataParseHelper;

    public UsbHelperTCP(Context context, Handler handler) {
        mContext = context;
        mHandler = handler;
        dataParseHelper = new DataParseHelper();
        dataParseHelper.setDataParseListener(new DataParseHelper.OnDataParsedListener() {
            @Override
            public void onMessageParsed(USBMessage message) {
                if (mHandler != null) {
                    Message msg = mHandler.obtainMessage();
                    msg.what = ServiceConstant.MSG_TYPE_USB_GET_MESSAGE;
                    msg.obj = message;
                    mHandler.sendMessage(msg);
                }
            }
        });

        try {
            serverSocket = new ServerSocket(TCP_PORT);
            startTcpServerThread();
            log("TCP server initialized on port " + TCP_PORT);
        } catch (IOException e) {
            log("Failed to initialize TCP server: " + e.getMessage());
        }
    }

    public void destroy() {
        isRunning = false;
        if (tcpServerThread != null) {
            try {
                tcpServerThread.join();
            } catch (InterruptedException e) {
                log("Error stopping TCP server thread: " + e.getMessage());
            }
        }
        if (serverSocket != null && !serverSocket.isClosed()) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                log("Error closing TCP server socket: " + e.getMessage());
            }
        }
        if (clientSocket != null && !clientSocket.isClosed()) {
            try {
                clientSocket.close();
            } catch (IOException e) {
                log("Error closing client socket: " + e.getMessage());
            }
        }
        log("TCP server destroyed");
    }

    public boolean sendData(byte[] data) {

        if (clientSocket == null || clientSocket.isClosed()) {
            log("No valid client socket to send data");
            return false;
        }

        new Thread(() -> {
            try {
                OutputStream outputStream = clientSocket.getOutputStream();
                outputStream.write(data);
                outputStream.flush();
                log("Sent " + data.length + " bytes via TCP");
            } catch (IOException e) {
                log("Failed to send data via TCP: " + e.getMessage());
            }
        }).start();
        return true;
    }

    private void startTcpServerThread() {
        isRunning = true;
        tcpServerThread = new Thread(() -> {
            while (isRunning && !Thread.interrupted()) {
                try {
                    Socket socket = serverSocket.accept();
                    log("New TCP client connected: " + socket.getInetAddress().getHostAddress());

                    synchronized (this) {
                        if (clientSocket != null && !clientSocket.isClosed()) {
                            clientSocket.close();
                        }
                        clientSocket = socket;
                    }

                    startListeningToClient(socket);
                } catch (IOException e) {
                    log("Error accepting TCP client: " + e.getMessage());
                }
            }
            log("TCP server thread stopped");
        });
        tcpServerThread.start();
    }

    private void startListeningToClient(Socket socket) {
        new Thread(() -> {
            try {
                InputStream inputStream = socket.getInputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while (!socket.isClosed() && (bytesRead = inputStream.read(buffer)) != -1) {
                    log("Received " + bytesRead + " bytes via TCP");
                    dataParseHelper.parseStream(buffer, bytesRead);
                }
            } catch (IOException e) {
                log("Error reading data from TCP client: " + e.getMessage());
            } finally {
                synchronized (this) {
                    if (clientSocket == socket) {
                        clientSocket = null;
                    }
                }
                try {
                    socket.close();
                    log("TCP client socket closed");
                } catch (IOException e) {
                    log("Error closing TCP client socket: " + e.getMessage());
                }
                log("Client socket closed");
            }
        }).start();
    }

    public void usbLog(String message) {
        log("USB Log: " + message);
    }

    private void log(String message) {
        Log.d(TAG, message);
    }

    public boolean checkUsbConnections() {
        log("Simulating check for USB connections via TCP");
        return true;
    }

    public boolean connectUsbDevice() {
        log("Simulating USB device connection via TCP");
        if (mHandler != null) {
            Message message = mHandler.obtainMessage();
            message.what = ServiceConstant.MSG_TYPE_USB_CONNECT;
            mHandler.sendMessage(message);
        }
        return true;
    }

    public void disconnectUsbDevice() {
        log("Simulating USB device disconnection via TCP");
        if (mHandler != null) {
            Message message = mHandler.obtainMessage();
            message.what = ServiceConstant.MSG_TYPE_USB_DISCONNECT;
            mHandler.sendMessage(message);
        }
    }

    public boolean checkUsbPermissionBeforeConnect() {
        log("Simulating USB permission check via TCP");
        return true;
    }
}